package com.videoaggre.zcl.api

import android.text.TextUtils
import com.videoaggre.zcl.utils.Logger
import okhttp3.*
import okio.Buffer
import java.io.IOException

/**
 * Created by zhy on 16/3/1.
 */
class LoggerInterceptor(private val showResponse: Boolean) : Interceptor {
    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): Response {
        if (Logger.isDebug) {
            val request = chain.request()
            logForRequest(request)
            val response = chain.proceed(request)
            return logForResponse(response)
        }
        return chain.proceed(chain.request())
    }

    private fun logForResponse(response: Response): Response {
        try {
            //===>response log
            Logger.e("========response'log=======")
            val builder = response.newBuilder()
            val clone = builder.build()
            Logger.e("url : " + clone.request.url)
            Logger.e("code : " + clone.code)
            Logger.e("protocol : " + clone.protocol)
            if (!TextUtils.isEmpty(clone.message)) Logger.e("message : " + clone.message)
            if (showResponse) {
                var body = clone.body
                if (body != null) {
                    val mediaType = body.contentType()
                    if (mediaType != null) {
                        Logger.e("responseBody's contentType : $mediaType")
                        if (isText(mediaType)) {
                            val resp = body.string()
                            Logger.e("responseBody's content : $resp")
                            body = ResponseBody.create(mediaType, resp)
                            return response.newBuilder().body(body).build()
                        } else {
                            Logger.e("responseBody's content : " + " maybe [file part] , too large too print , ignored!")
                        }
                    }
                }
            }
            Logger.e("========response'log=======end")
        } catch (e: Exception) {
//            e.printStackTrace();
        }
        return response
    }

    private fun logForRequest(request: Request) {
        try {
            val url = request.url.toString()
            val headers = request.headers
            Logger.e("========request'log=======")
            Logger.e("method : " + request.method)
            Logger.e("url : $url")
            if (headers != null && headers.size > 0) {
                Logger.e("headers : $headers")
            }
            val requestBody = request.body
            if (requestBody != null) {
                val mediaType = requestBody.contentType()
                if (mediaType != null) {
                    Logger.e("requestBody's contentType : $mediaType")
                    if (isText(mediaType)) {
                        Logger.e("requestBody's content : " + bodyToString(request))
                    } else {
                        Logger.e("requestBody's content : " + " maybe [file part] , too large too print , ignored!")
                    }
                }
            }
            Logger.e("========request'log=======end")
        } catch (e: Exception) {
//            e.printStackTrace();
        }
    }

    private fun isText(mediaType: MediaType): Boolean {
        if (mediaType.type != null && mediaType.type == "text") {
            return true
        }
        if (mediaType.subtype != null) {
            if (mediaType.subtype == "json" || mediaType.subtype == "xml" || mediaType.subtype == "html" || mediaType.subtype == "x-www-form-urlencoded" || mediaType.subtype == "webviewhtml") return true
        }
        return false
    }

    private fun bodyToString(request: Request): String {
        return try {
            val copy = request.newBuilder().build()
            val buffer = Buffer()
            copy.body!!.writeTo(buffer)
            buffer.readUtf8()
        } catch (e: IOException) {
            "something error when show requestBody."
        }
    }

    companion object {
        const val TAG = "OkHttpUtils"
    }

}